package org.budo.support.lang.counter;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.springframework.util.Assert;

/**
 * 计数器
 * 
 * @author lmw
 */
public class Counter {
    private static final Map<String, Counter> _CACHE_MAP = new ConcurrentHashMap<String, Counter>();

    private String key;

    private AtomicLong atomicLong = new AtomicLong(0);

    private Counter() {
    }

    public static Counter of(String key) {
        Assert.hasText(key, "key can not be null, key=" + key);

        Counter counter = _CACHE_MAP.get(key);
        if (null != counter) {
            return counter;
        }

        synchronized (Counter.class) {
            counter = _CACHE_MAP.get(key);
            if (null != counter) {
                return counter;
            }

            counter = new Counter();
            counter.key = key;
            _CACHE_MAP.put(key, counter);
            return counter;
        }
    }

    public Counter increment() {
        this.atomicLong.incrementAndGet();
        return this;
    }

    public Integer getValue() {
        return (int) this.atomicLong.get();
    }

    public Counter setValue(Number value) {
        this.atomicLong.set(value.longValue());
        return this;
    }

    public boolean isMultipleOf(int radix) {
        return 0 == this.getValue() % radix;
    }

    @Override
    public String toString() {
        return super.toString() + ", value=" + this.atomicLong + ", key=" + this.key;
    }
}